package com.projeto.web;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import com.projeto.business.controller.CustomerController;
import com.projeto.business.controller.EventController;
import com.projeto.business.controller.UserController;
import com.projeto.infra.PasswordEncryptor;
import com.projeto.persistence.Customer;
import com.projeto.persistence.GroupTable;
import com.projeto.persistence.User;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import org.primefaces.context.RequestContext;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

@ManagedBean
@SessionScoped
public class UserBackBean implements Serializable {

    private String password;
    /**
     *
     */
    private static final long serialVersionUID = -8717331129461237636L;
    private List<User> userList;
    private Collection<Customer> customerList;
    private User selectedUser = new User();
    private List<GroupTable> groupTables;
    @EJB
    UserController userBean;
    @EJB
    CustomerController customerBean;
    @EJB
    EventController eventEJB;
    private boolean exibeDialog;
    private boolean isNew;
    private StreamedContent report;

    public void addUser() {
        RequestContext.getCurrentInstance().reset("userDialogForm");
        selectedUser = new User();
        isNew = true;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean isIsNew() {
        return isNew;
    }

    public void setIsNew(boolean isNew) {
        this.isNew = isNew;
    }

    public List<User> getUserList() {

        if (userList == null) {
            userList = userBean.findAll();
        }
        return userList;
    }

    public List<GroupTable> getGroupTables() {
        if (groupTables == null) {
            groupTables = userBean.findAllGrouptTables();
        }
        return groupTables;
    }

    public void reset() {
        userList = userBean.findAll();
        setPassword(null);
        RequestContext.getCurrentInstance().update("form");
        RequestContext.getCurrentInstance().reset("userDialogForm");
        FacesContext.getCurrentInstance().getMessageList().clear();
        
    }

    public StreamedContent getReport() throws JRException, IOException {
        if (report == null) {
            pdf();
        }
        return report;
    }

    public void setReport(StreamedContent report) {
        this.report = report;
    }

    public void saveUser() {
        try {
            selectedUser.setPassword(PasswordEncryptor.encrypt(getPassword()));
            userBean.save(selectedUser);
            FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_INFO, "User " + selectedUser.getName() + " Saved!", "User saved"));

        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(UserBackBean.class.getName()).log(Level.SEVERE, null, ex);
            FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ocorreu um erro interno", "User Not saved"));

        } catch (UnsupportedEncodingException ex) {
            FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ocorreu um erro interno", "User Not saved"));

        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ocorreu um erro interno ", "User Not saved"));

        }
    }

    public boolean isExibeDialog() {
        return exibeDialog;
    }

    public void setExibeDialog(boolean exibeDialog) {
        this.exibeDialog = exibeDialog;
    }

    public Collection<Customer> getCustomerList() {
        if (customerList == null) {
            customerList = customerBean.findAll();
        }
        return customerList;
    }

    public UserController getUserBean() {
        return userBean;
    }

    public void setUserBean(UserController userBean) {
        this.userBean = userBean;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    public User getSelectedUser() {
        return selectedUser;
    }

    public void setSelectedUser(User selectedUser) {
        this.selectedUser = selectedUser;
    }

    public UserBackBean() {
    }

    public void pdf() throws JRException, IOException {

        JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(userBean.findAll());
        String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reports/usersReport.jasper");
        // Carrega o xml de definição do relatório
        try {
            FacesContext context = FacesContext.getCurrentInstance();
            HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
            JasperPrint impressao = JasperFillManager.fillReport(reportPath, new HashMap(), beanCollectionDataSource);
            // Exporta o relatório
            JasperExportManager.exportReportToPdfStream(impressao, response.getOutputStream());
            // Salva o estado da aplicação no contexto do JSF
            context.getApplication().getStateManager().saveView(context);

            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            response.getOutputStream().write(buffer.toByteArray());
            InputStream is = new ByteArrayInputStream(buffer.toByteArray());

            // Fecha o stream do response
            context.responseComplete();
            report = new DefaultStreamedContent(is, "application/pdf", "ohyeah.pdf");
        } catch (Exception e) {
            //setExibeDialog(true);
            //mensagem += e;
        }
    }

    public void imprime() {
        try {
            JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(userBean.findAll());
            String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reports/usersReport.jasper");
        
            FacesContext facesContext = FacesContext.getCurrentInstance();

            facesContext.responseComplete();

            ServletContext scontext = (ServletContext) facesContext.getExternalContext().getContext();

            //JasperPrint jasperPrint = JasperFillManager.fillReport(scontext.getRealPath("/WEB-INF/report/relatorio_funcionarios_por_cargo.jasper"), parameters, ds);
            JasperPrint jasperPrint = JasperFillManager.fillReport(reportPath, new HashMap(), beanCollectionDataSource);

            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            JRPdfExporter exporter = new JRPdfExporter();

            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);

            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);

            exporter.exportReport();

            byte[] bytes = baos.toByteArray();

            if (bytes != null && bytes.length > 0) {

                HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();

                response.setContentType("application/pdf");

                response.setHeader("Content-disposition", "inline; filename=\"relatorioPorData.pdf\"");

                response.setContentLength(bytes.length);

                ServletOutputStream outputStream = response.getOutputStream();

                outputStream.write(bytes, 0, bytes.length);

                outputStream.flush();

                outputStream.close();

            }

        } catch (Exception e) {

            e.printStackTrace();

        }
    }
}
